--奖池管理器
local skynet = require "skynet"
local cluster = require "skynet.cluster"
local queue = require "skynet.queue"
local filename = "jackpotmgr.lua"
local filelog = require "filelog"
local slottool = require "slottool"
local timetool = require "timetool"
local tabletool = require "tabletool"
local timer = require "timer"

--是否开启奖池
local is_runjackpot = false

------------

--奖池管理器
local JackpotMgr = {
    CMD = {},
    timers = {},
    jackpot_totable = {},    --奖池关联的桌子
 }

--锁
local cs_jackpot = queue()

--平衡因子
local balance_f = 0

--最大奖池数量，最多20个
local max_jackpot_num = 2

--开奖倒计时,单位s
local open_jackpot_countdown = 30


-----------

--设置奖池开奖定时器
function JackpotMgr.set_open_jackpot_timer(gamename,jackpot_id)
    if JackpotMgr.timers[jackpot_id] then
        return tabletool.deepcopy(JackpotMgr.timers[jackpot_id])
    end

    local now = timetool.get_time()
    local open_jackpot_timestamp = now + open_jackpot_countdown
    local timer_id = timer.settimer(open_jackpot_countdown * 100, "open_jackpot", {jackpot_id = jackpot_id})
    local jackpot_timer = {
        gamename = gamename,
        timer_id = timer_id,
        outtime = open_jackpot_timestamp,
        delaytime = open_jackpot_countdown,
    }
    JackpotMgr.timers[jackpot_id] = jackpot_timer

    return tabletool.deepcopy(jackpot_timer)
end

--
--  修改奖池
--
function JackpotMgr.change_jackpot(gamename, jackpot_id, val, rid_values)
    local nodename,gametype = string.match(gamename,"(%a+)_(%a+)")
    local comment = {jackpot_id = jackpot_id }
    local status,result = skynet.pcall(cluster.call,"gatenode", ".router", "open_jackpot_" .. gametype, nodename, rid_values, comment)
    if not status then
        filelog.sys_error("change_jackpot call failed!")
        return false
    end
    return result
end

---------------------------------------
----------

--初始化桌子奖池
--1个场次一个奖池
function JackpotMgr.CMD.init_table_jackpot(gamename,leveltype,tableservice)
    local function real_init_table_jackpot(gamename,leveltype,tableservice)
        --local jackpot_id = balance_f % max_jackpot_num + 1
        --balance_f = (balance_f + 1) % max_jackpot_num
        local jackpot_id = tonumber(leveltype) or 1

        --判断奖池是否已存在,不存在则创建
        local jackpot_money = slottool.get_jackpot_from_redis(gamename,jackpot_id,true)
        JackpotMgr.CMD.create_jackpot_totable(jackpot_id,tableservice)

        return jackpot_id,jackpot_money
    end

    return cs_jackpot(real_init_table_jackpot,gamename,leveltype,tableservice)
end

--获取桌子奖池开奖定时器
function JackpotMgr.CMD.get_jacpot_timer(gamename, jackpot_id)
    return JackpotMgr.set_open_jackpot_timer(gamename,jackpot_id)
end

--[Comment]
-- 处理发来的timer命令消息
--
function JackpotMgr.CMD.timer( msgname, ...)
    local f = JackpotMgr.CMD[msgname]
    if f == nil then
        return
    end
    return f(...)
end

--
--开奖
--
function JackpotMgr.CMD.open_jackpot(timerid, request)
    local jackpot_id = request.jackpot_id or 0
    if not JackpotMgr.timers[jackpot_id] then
        return
    end

    --开奖
    local player_list = {}
    local jackpot_item = JackpotMgr.timers[jackpot_id]
    local tables = JackpotMgr.jackpot_totable[jackpot_id]
    for _,tableservice in pairs(tables) do
        local isok,players = skynet.pcall(skynet.call, tableservice, "lua", "cmd", "get_player_list")
        if isok and players then
            for _,v in pairs(players) do
                table.insert(player_list,v)
            end
        end
    end
    local award_list,total_coin = skynet.call(".slotmgr","lua","handle_open_jackpot",jackpot_item.gamename, jackpot_id, player_list)

    --修改奖池金额
    local rid_values = {}
    for _,awarditem in pairs(award_list) do
        rid_values[awarditem.rid] = {}
        rid_values[awarditem.rid].value = awarditem.award_money_num
    end
    local status = JackpotMgr.change_jackpot(jackpot_item.gamename, jackpot_id, -total_coin, rid_values)

    --重新获取奖池金额
    local cur_jackpot_money = slottool.get_jackpot_from_redis(jackpot_item.gamename,jackpot_id)

    --重置开奖倒计时
    JackpotMgr.timers[jackpot_id] = nil
    local jackpot_timer = JackpotMgr.set_open_jackpot_timer(jackpot_item.gamename, jackpot_id)
    local noticemsg = {
        open_jackpot_timestamp = jackpot_timer.outtime,
        openjackpot_list = award_list,
        cur_jackpot_money = cur_jackpot_money,
    }

    --开奖失败
    if not status then
        return false
    end

    --通知桌子开奖
    for _,tableservice in pairs(tables) do
        skynet.pcall(skynet.send, tableservice, "lua", "cmd", "open_jackpot", noticemsg)
    end
    
    return true
end

--
--建立桌子到奖池的映射
--
function JackpotMgr.CMD.create_jackpot_totable(jackpot_id, tableservice)
    JackpotMgr.jackpot_totable[jackpot_id] = JackpotMgr.jackpot_totable[jackpot_id] or {}
    JackpotMgr.jackpot_totable[jackpot_id][tableservice] = tableservice
end

--取消桌子到奖池的映射
function JackpotMgr.CMD.delete_jackpot_totable(jackpot_id, tableservice)
    if JackpotMgr.jackpot_totable[jackpot_id] then
        JackpotMgr.jackpot_totable[jackpot_id][tableservice] = nil
    end
end

-------------

skynet.start(function()
    skynet.dispatch("lua",function(session, source, cmd, ...)
        if is_runjackpot then
            local f = JackpotMgr.CMD[cmd]
            if f then
                skynet.retpack(f(...))
            else
                skynet.retpack()
            end
        else
            skynet.retpack()
        end
    end)
end)